--[[
客户端发送上来的消息请求格式
req = {
  cmd = xxx --模块的指令头
  sub = xxx --模块的具体操作类型
  msg = {} --发送的数据
}

发送给客户端的消息格式
rsp = {
  cmd = xxx --模块的指令头
  sub = xxx --模块的具体操作类型
  ret = {} --发送的数据
  err = xxx --错误类型
}
]]

require "sharefunc"
local skynet = require "skynet"

local Message = {}

Message.handler = {}

--[[
注册消息处理回调
]]
function Message.reg(cmd, sub, cb)
    assert(cmd, "register the msg failed! the cmd is nil")
    assert(sub, "register the msg failed! the sub is nil")
    assert("function" == type(cb), "register the msg failed! the callback is not a function.")
    
    Message.handler[cmd] = Message.handler[cmd] or {}

    assert(not Message.handler[cmd][sub], "register the msg failed! cmd already registered.cmd=" .. tostring(cmd) .. ",sub=" .. tostring(sub))

    -- print(string.format("register the msg: cmd = %s, sub = %s success!", cmd, sub))
    Message.handler[cmd][sub] = cb
end

--[[
删除消息
]]
function Message.remove(cmd, sub)
  if Message.handler[cmd] and Message.handler[cmd][sub] then
    Message.handler[cmd][sub] = nil
  end
end

--[[
清空所有注册的消息
]]
function Message.clear()
    Message.handler = {}
end

--[[
消息分发
]]
function Message.dispatch(req)
    local cmd = req.cmd
    local sub = req.sub

    local cb = Message.handler[cmd][sub]
    if "function" ~= type(cb) then
        skynet.error("handle the msg failed! not found the msg: cmd=", cmd, ",sub=", sub)
    end
    local ok,ret,result = xpcall(cb,sharefunc.exception,req)
    if not ok then
        skynet.error("Dispatch.to call failed =",cmd,sub,ret)
    end
    return ret,result
end

return Message

